#region Copyright (C) 2007 Jens Winter

//Copyright (C) 2007 Jens Winter

//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.

//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Flynn.Core;

namespace Flynn
{
	public class VersioningsCollector
	{
		public IDictionary<string, string> CollectVersionings(string directory)
		{
			IDictionary<string, string> versionings = new Dictionary<string, string>();

			CollectVersioningsInDirectory(directory, versionings);

			return versionings;
		}

		private static void CollectVersioningsInDirectory(string directory, IDictionary<string, string> versionings)
		{
			string[] files = Directory.GetFiles(directory, "*.dll", SearchOption.TopDirectoryOnly);
			foreach (string file in files)
			{
				CollectVersioningsInFile(file, versionings);
			}
		}

		private static void CollectVersioningsInFile(string file, IDictionary<string, string> versionings)
		{
			Assembly assembly = null;
			try
			{
				assembly = Assembly.LoadFrom(file);
			}
			catch
			{
			}

			if (assembly != null)
				CollectVersioningsInAssembly(assembly, versionings);
		}

		private static void CollectVersioningsInAssembly(Assembly assembly, IDictionary<string, string> versionings)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (!type.IsAbstract && typeof (IVersioning).IsAssignableFrom(type))
				{
					object[] versioningAttributes = type.GetCustomAttributes(typeof (VersioningAttribute), false);
					if (versioningAttributes.Length > 0)
						versionings.Add(((VersioningAttribute) versioningAttributes[0]).FriendlyName, type.AssemblyQualifiedName);
					else
					{
						if (type.Name.EndsWith("Versioning"))
							versionings.Add(type.Name.Substring(0, type.Name.Length - "Versioning".Length), type.AssemblyQualifiedName);
						else
							versionings.Add(type.AssemblyQualifiedName, type.AssemblyQualifiedName);
					}
				}
			}
		}
	}
}